package com.example.lottery.service.impl;

import com.example.lottery.common.errorcode.ServiceErrorCodeConstants;
import com.example.lottery.common.exception.ServiceException;
import com.example.lottery.common.utils.CaptchaUtil;
import com.example.lottery.common.utils.MailUtil;
import com.example.lottery.common.utils.RedisUtil;
import com.example.lottery.common.utils.RegexUtil;
import com.example.lottery.dao.datobject.Encrypt;
import com.example.lottery.dao.mapper.UserMapper;
import com.example.lottery.service.VerificationCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class VerificationCodeServiceImpl implements VerificationCodeService {
    // Redis key 前缀
    private static final String EMAIL_VERIFICATION_CODE_PREFIX = "EMAIL_VERIFICATION_CODE_";
    private static final String PHONE_EMAIL_MAPPING_PREFIX = "PHONE_EMAIL_MAPPING_";

    // 过期时间（秒）
    private static final Long VERIFICATION_CODE_TIMEOUT = 60L;

    /**
     * 这个映射缓存关系怎么理解？
     */
    private static final Long PHONE_EMAIL_MAPPING_TIMEOUT = 3600L; // 映射关系缓存1小时

    @Autowired
    private MailUtil mailUtil;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserMapper userMapper;


//    @Value("${email.verification.subject:登录验证码}")
//    private String emailSubject;

    /**
     * 发送验证码到手机号关联的邮箱（核心方法）
     */
    @Override
    public void sendVerificationCode(String phoneNumber) {
        // 1. 校验手机号格式
        if (!RegexUtil.checkMobile(phoneNumber)) {
            throw new ServiceException(ServiceErrorCodeConstants.PHONE_NUMBER_ERROR);
        }

        // 2. 根据手机号获取关联邮箱
        String email = getEmailByPhone(phoneNumber);
        if (email == null) {
            throw new ServiceException(ServiceErrorCodeConstants.MAIL_ERROR);
        }

        // 3. 生成4位数字验证码
        String code = CaptchaUtil.getCaptcha(4);

        // 4. 发送邮件
        String content = buildEmailContent(code, phoneNumber);
//        mailUtil.sendEmail(email, emailSubject, content);
        mailUtil.sendMail(email,content);

        // 5. 缓存验证码，key使用手机号，60秒过期
        redisUtil.set(EMAIL_VERIFICATION_CODE_PREFIX + phoneNumber, code, VERIFICATION_CODE_TIMEOUT);

        // 6. 记录日志（可选）
        System.out.println("登录验证码已发送到手机号 " + phoneNumber + " 关联的邮箱: " + email);
    }

    /**
     * 从缓存中获取验证码（主要用于调试和测试）
     */
    @Override
    public String getVerificationCode(String phoneNumber) {
        if (!RegexUtil.checkMobile(phoneNumber)) {
            throw new ServiceException(ServiceErrorCodeConstants.PHONE_NUMBER_ERROR);
        }
        //获取验证码
        return redisUtil.get(EMAIL_VERIFICATION_CODE_PREFIX + phoneNumber);
    }


    /**
     * 验证验证码
     */

//    public boolean verifyCode(String phoneNumber, String code) {
//        //code.trim().isEmpty()  用于验证码专用的
//        if (!RegexUtil.checkMobile(phoneNumber) || code == null || code.trim().isEmpty()) {
//            return false;
//        }
//
//
//        String cachedCode = getVerificationCode(phoneNumber);
//        return code != null && code.equals(cachedCode);
//    }

    /**
     * 根据手机号获取邮箱地址
     */
    private String getEmailByPhone(String phoneNumber) {
        // 先从缓存查询
        String cachedEmail = redisUtil.get(PHONE_EMAIL_MAPPING_PREFIX + phoneNumber);
        if (cachedEmail != null) {
            return cachedEmail;
        }

        // 从数据库查询用户信息
        String email = userMapper.findEmailByPhone(new Encrypt(phoneNumber));

        if (email != null) {
            // 缓存映射关系1小时，这样就不用每次都从数据库里面查email，存放email的这个缓存时1h的有效期
            //我觉得1h设置的很好，假设有一种情况，用户18030745581对应A邮箱，刚开始发送了一个验证码 60秒过期了，完全可以直接从缓存中
            //读取A邮箱，因为A账户是个定值，不用从数据库再次查A邮箱
            redisUtil.set(PHONE_EMAIL_MAPPING_PREFIX + phoneNumber, email, PHONE_EMAIL_MAPPING_TIMEOUT);
        }

        return email;
    }

    /**
     * 构建邮件内容
     */
    private String buildEmailContent(String code, String phoneNumber) {
        return String.format(
                "<!DOCTYPE html>" +
                        "<html>" +
                        "<head>" +
                        "<meta charset=\"UTF-8\">" +
                        "<title>登录验证码</title>" +
                        "</head>" +
                        "<body>" +
                        "<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e0e0e0; border-radius: 8px;\">" +
                        "<h2 style=\"color: #333; text-align: center; margin-bottom: 30px;\">登录验证码</h2>" +
                        "<p>尊敬的 <strong>%s</strong> 用户，你的验证码是 <strong style=\"color: #e74c3c; font-size: 18px;\">%s</strong></p>" +
                        "<div style=\"background-color: #f8f9fa; padding: 15px; border-radius: 6px; margin: 25px 0; text-align: center; border-left: 4px solid #1890ff;\">" +
                        "<h1 style=\"color: #e74c3c; margin: 0; font-size: 32px; letter-spacing: 5px;\">%s</h1>" +
                        "</div>" +
                        "<p style=\"color: #ff4d4f;\">验证码有效期为 <strong>60秒</strong>，请尽快使用。</p>" +
                        "<div style=\"margin-top: 30px; padding-top: 20px; border-top: 1px solid #f0f0f0; color: #999; font-size: 12px;\">" +
                        "<p>如果这不是您的操作，请忽略此邮件。</p>" +
                        "<p>系统自动发送，请勿回复。</p>" +
                        "<p style=\"text-align: center; margin-top: 20px; color: #666; font-size: 14px;\">Maybe抽奖系统</p>" +
                        "</div>" +
                        "</div>" +
                        "</body>" +
                        "</html>",
                phoneNumber, code, code
        );
    }

}
